新しい画面にデータを送信する
多くの場合、新しい画面に移動するだけでなく、 ただし、データも画面に渡します。 たとえば、次のような情報を渡したい場合があります。 タップされた項目。
覚えておいてください: 画面は単なるウィジェットです。 この例では、todo のリストを作成します。 Todo がタップされると、新しい画面 (ウィジェット) に移動します。 todo に関する情報を表示します。 このレシピでは次の手順を使用します。
- todoクラスを定義します。
- Todoのリストを表示します。
- Todoに関する情報を表示できる詳細画面を作成します。
- データを詳細画面に移動して渡します。
1. todoクラスを定義する
まず、todo を表す簡単な方法が必要です。この例では、 タイトルと説明という 2 つのデータを含むクラスを作成します。
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
2. Todoリストを作成する
次に、todo のリストを表示します。この例では、 20 個の Todo をリストビューを使用して表示します。 リストの操作の詳細については、 を参照してくださいリストを使用するレシピ。
Todoリストを生成する
final todos = List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
);
ListView を使用して Todo のリストを表示する
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
),
ここまでは順調ですね。 これにより 20 個の Todo が生成され、ListView に表示されます。
3. リストを表示するTodo画面を作成する
このために、StatelessWidget
。私たちはそれをそう呼んでいますTodosScreen
。
このページの内容は実行中に変更されないため、
リストを要求する必要があります
このウィジェットの範囲内の todo の数。
私たちは、ListView.builder
戻るウィジェットの本体としてbuild()
。
これにより、リストが画面に表示されるので、すぐに始めることができます。
class TodosScreen extends StatelessWidget {
// Requiring the list of todos.
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
//passing in the ListView.builder
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
),
);
}
}
Flutter のデフォルトのスタイルを使用すれば、苦労せずに作業を進めることができます。 後でやりたいこと!
4. Todoに関する情報を表示する詳細画面を作成する
次に、2番目の画面を作成します。画面のタイトルには、 todo のタイトル、画面の本文に説明が表示されます。
詳細画面は普通なのでStatelessWidget
、
ユーザーに入力を要求するTodo
UIで。
次に、指定された todo を使用して UI を構築します。
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({super.key, required this.todo});
// Declare a field that holds the Todo.
final Todo todo;
@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
5. 詳細画面に移動してデータを渡します
とともにDetailScreen
所定の位置に、
ナビゲーションを実行する準備ができました。
この例では、次の場所に移動します。DetailScreen
ユーザーのとき
リスト内の ToDo をタップします。 todo をに渡しますDetailScreen
。
ユーザーのタップをキャプチャするにはTodosScreen
、書きますonTap()
のコールバックListTile
ウィジェット。以内onTap()
折り返し電話、
使用Navigator.push()
方法。
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
インタラクティブな例
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}
class TodosScreen extends StatelessWidget {
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({super.key, required this.todo});
// Declare a field that holds the Todo.
final Todo todo;
@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
または、RouteSettings を使用して引数を渡します
最初の 2 つの手順を繰り返します。
引数を抽出する詳細画面を作成する
次に、タイトルと説明文を抽出して表示する詳細画面を作成します。Todo
。にアクセスするには、Todo
、 使用ModalRoute.of()
方法。このメソッドは、現在のルートを引数とともに返します。
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
詳細画面に移動して引数を渡します
最後に、に移動しますDetailScreen
ユーザーがタップしたとき
あるListTile
ウィジェットを使用してNavigator.push()
。
の一部として引数を渡しますRouteSettings
。
のDetailScreen
これらの引数を抽出します。
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings. The
// DetailScreen reads the arguments from these settings.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
)
完全な例
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}
class TodosScreen extends StatelessWidget {
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings. The
// DetailScreen reads the arguments from these settings.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}